#include "fonction.h"
#include "instructionsimple.h"

fonction::fonction()
{
	valide=1;
}

fonction::fonction(int rk,const string& nom, stringstream& S):rang(rk),nom_func(nom),flux_erreur(&S)/*,fonction_traduite(nom_func)*/
{
	valide=1;
	
	fonction_traduite = fonctioncpp(nom_func);
	
}

fonction::fonction(const fonction& f)
{
	nom_func = f.nom_func;
	variables = f.variables;
	valide = f.valide;
	vect_ins_string = f.vect_ins_string;
	rang=f.rang;
	parametres=f.parametres;
	fonction_traduite=f.fonction_traduite;
}

const string& fonction::getName()
{
	return nom_func;
}

bool fonction::isValid()
{
	return valide;
}

void fonction::printParameter()
{
	map<string,int>::iterator it;
	it=variables.begin();
	while (it!=variables.end())
	{
		cout<<(*it).first<<endl;
		it.operator++();
	}
	
}

void fonction::addVariable(const string& nom_var)
{

  variables.insert(pair<string,int>(nom_var,0));
  
}

void fonction::addParameter(const string& nom_var)
{
	
  variables.insert(pair<string,int>(nom_var,true));
 
  parametres.push_back(nom_var);
}

void fonction::addFonction(const string& nom_var, int nbPara)
{
	variables.insert(pair<string,int>(nom_var,nbPara));
}


void fonction::initialize(const string& nomvar)
{
  map<string,int>::iterator it = variables.find(nomvar);
  
  if (it!=variables.end()) (*it).second=1;
}

void fonction::addInstruction(int rk,const string& typ, const string& inst)
{
	rang=rk;
	instructionsimple I(typ,inst,this,false);
	
	if(fonction_traduite.isEmpty())
	{
		stringstream entete,S;
		entete <<"int "<<nom_func<<"(";
		if(parametres.size()>0) entete<<"int ";
		for(int i=0;i<parametres.size();i++)
		{
			if(i==(parametres.size()-1)) entete<<parametres[i];
			else entete<<parametres[i]<<", ";
		}
		entete<<")";
		
		entete <<"{";
		fonction_traduite.addInst(entete.str());
	}
	
	if(I.isValid())
	{
		string S[2]= {typ, inst};
		
		pair<map<int,string[2]>::iterator,bool> X = vect_ins_string.insert(pair<int,string[2]>(rang,S));
		
		if (X.second==0) cout<<endl<<"Insertion :"<<rang<<"  :"<<typ<<" "<<inst<<" Failed"<<endl;
		
		valide = valide && 1;
		
		fonction_traduite.addInst(I.translate());
		
		
	}
	else
	{
		valide = valide && 0;
		
	}
	
	
}


bool fonction::checkVar(const string& nomvar)
{
  if (variables.find(nomvar)!=variables.end() ) return 1;
  else return 0;
}

bool fonction::checkFonction(const string& nomvar)
{
  if (variables.find(nomvar)!=variables.end() ) return 1;
  else return 0;
}

int fonction::getNbParaFonction(const string& nomvar)
{
	map<string,int>::iterator it = variables.find(nomvar);
	
	if (it!=variables.end()) return (*it).second;
	
	else return 0;
}



bool fonction::isInitialized(const string& nomvar)
{
  map<string,int>::iterator it = variables.find(nomvar);
  
  if (it!=variables.end() && ((*it).second != 0)) return 1;
  else return 0;
}


fonctioncpp fonction::translate()
{
	
	stringstream S;
	S.clear();
	S <<"}"<<endl;
	fonction_traduite.addInst(S.str());
	
	return fonction_traduite;
}

void fonction::listInstructions()
{
	cout<<nom_func<<" :"<<endl;
	
	map<int,string[2]>::iterator it;
	
	
	
	for(it = vect_ins_string.begin(); it != vect_ins_string.end() ; it++)
	{
		cout << (*it).first <<" :"<<(*it).second[0]<<" "<<(*it).second[1]<<endl;
	}
	
	
}


const void fonction::errorLog(const string & message)
{
  
 
  if (message != "") (*flux_erreur)<<nom_func<<":ligne "<<rang<<" :"<<message<<endl;
  
  
}


